# encoding: utf-8
# Copyright 2012, Google Inc. All Rights Reserved.
"""
Block serving handler. Returns a block variant from memcache, from storage
or from the filesystem (in that order)
"""
__author__ = 'davidthorpe@google.com'

import sys,os,logging
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

# import local libraries
sys.path.append(os.path.join(os.path.dirname(__file__), 'lib'))
import constants
import cache

# Create cache
store_cache = cache.StoreCache()
state_cache = store_cache.state

class BlockHandler(webapp.RequestHandler):
	def query_string(self):
		query_string = self.request.query_string
		if query_string:
			return "?%s" % query_string
		else:
			return ""
		
	def get_block(self,name,variant):
		logging.debug("get_block: (name,variant) = (%s,%s)" % (name,variant))
		entity = None
		# if variant is None, then retrieve current block variant
		if variant==None:
			variant = state_cache.get_state_value(name)
			logging.debug("get_block: current variant state = (%s,%s)" % (name,variant))
		# if variant, then retrieve block
		if variant:
			entity = store_cache.get_block_variant(name,variant)
		if not entity:
			entity = store_cache.new_block_variant(name,long(1))
		# if block, return the block
		logging.debug("Returning %s for (%s,%s)" % (entity,name,variant))
		return entity
	
	def set_nocache(self):
		self.response.headers["Pragma"]= "no-cache"
		self.response.headers["Cache-Control"]="no-cache"
		self.response.headers["Expires"]="Thu, 01 Dec 1994 16:00:00"

	def get(self,name,variant):
		try:
			# obtain (name,variant)
			name = unicode(name)
			if variant:
				variant = long(variant)
			else:
				variant = None
			block_variant = self.get_block(name,variant)
			if block_variant==None:
				raise cache.FileNotFound("%s" % self.request.url)
			# ensure blocks are not cached
			self.set_nocache()
			# return response
			self.response.out.write(block_variant.get_content())
		except cache.FileNotFound, e:
			self.error(404)
			self.response.headers['Content-Type'] = "text/plain"
			self.response.out.write("Resource not found: %s\n\n" % e)
#		except Exception, e:
#			self.error(500)
#			self.response.headers['Content-Type'] = "text/plain"
#			self.response.out.write("Server Error: %s\n\n" % e)

	def post(self,name,variant):
		try:
			# obtain (name,variant)
			name = unicode(name)
			if variant:
				variant = long(variant)
			else:
				variant = None
			entity = self.get_block(name,variant)
			if entity==None:
				raise cache.FileNotFound("%s" % self.request.url)
			# set variables for the block
			for arg in self.request.arguments():
				tuple_name = unicode(arg)
				tuple_value = unicode(self.request.get(arg))
				logging.debug("<Block %s Variant %d> Tuple %s => %s" % (entity.name,entity.value,tuple_name,tuple_value))
				entity.set_tuple(tuple_name,tuple_value)
			# save the block
			store_cache.save_block_variant(entity)
			# TODO: increment counters, etc.
			# ensure blocks are not cached
			self.set_nocache()
			# return response
			self.response.out.write(entity.get_content())
		except cache.FileNotFound, e:
			self.error(404)
			self.response.headers['Content-Type'] = "text/plain"
			self.response.out.write("Resource not found: %s\n\n" % e)
#		except Exception, e:
#			self.error(500)
#			self.response.headers['Content-Type'] = "text/plain"
#			self.response.out.write("Server Error: %s\n\n" % e)

application = webapp.WSGIApplication([
	(r'/b/(\w+)()',BlockHandler),
	(r'/b/(\w+)/()',BlockHandler),
	(r'/b/(\w+)/(\d+)',BlockHandler)
],debug=constants.DEBUG)

def main():
	if constants.DEBUG:
		logging.getLogger().setLevel(logging.DEBUG)
	else:
		logging.getLogger().setLevel(logging.INFO)
	run_wsgi_app(application)

if __name__ == "__main__":
	main()
